using System.Text;
using Microsoft.Extensions.Logging;
using ORS.OrderRobot.ServiceContracts;
using ORS.OrderRobot.ServiceContracts.Dtos;
using ORS.OrderRobot.ServiceContracts.Dtos.Api;
using ORS.OrderRobot.ServiceContracts.ThridPartApi;
using ORS.OrderRobot.IOC;
using System.Text.Json;

namespace ORS.OrderRobot.Service.ThridPartApi
{
    public class ThirdAccountService : IThirdAccountService, ISingleton
    {
        private readonly IHttpHelper _httpHelper;
        private readonly ILogger<ThirdAccountService> _logger;
        public ThirdAccountService(IHttpHelper httpHelper, ILogger<ThirdAccountService> logger)
        {
            _httpHelper = httpHelper;
            _logger = logger;
        }
        /// <summary>
        /// 获取用户的购物车信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<BasketResDto> GetAccountBasketAsync(GetCustomerCartInput input)
        {
            var url = $"/customers/{input.CustomerId}/baskets";
            var requestInfo = new RequestInfo
            {
                BearerToken = input.Token,
            };
            var httpResult = await _httpHelper.SendAndParseAsync<BasketResDto>(url, HttpMethod.Get, requestInfo);
            if (httpResult.StatusCode != 200)
            {
                var message = $"获取用户的购物车信息失败,CustomerId:{input.CustomerId}";
                _logger.LogError("{Message}, httpResult: {@httpResult}", message, httpResult);
                throw new Exception($"{message}, httpResult: {JsonSerializer.Serialize(httpResult)}");
            }
            if (httpResult.Body == null)
            {
                var message = $"解析用户的购物车信息失败,CustomerId:{input.CustomerId}";
                _logger.LogError("{Message}, httpResult: {@httpResult}", message, httpResult);
                throw new Exception($"{message}, httpResult: {JsonSerializer.Serialize(httpResult)}");
            }
            if(httpResult.Body.Baskets.Count == 0)
            {
                var message = $"获取到的购物车的Baskets为空,CustomerId:{input.CustomerId}";
                _logger.LogError("{Message}, httpResult: {@httpResult}", message, httpResult);
                throw new CodeException(200,$"{message}, httpResult: {JsonSerializer.Serialize(httpResult)}");
            }
            return httpResult.Body;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task<LoginResultInfo?> LoginAsync(string email, string password)
        {
            var url = $"/customers/auth";
            var plainBytes = Encoding.UTF8.GetBytes($"{email}:{password}");
            var basicToken = $"Basic {Convert.ToBase64String(plainBytes)}";
            var headers = new Dictionary<string, string> { { "authorization", basicToken } };
            var body = new Dictionary<string, string>
            {
                { "type","credentials"}
            };
            var httpResult = await _httpHelper.SendAndParseAsync<LoginResultInfo>(url, HttpMethod.Post, new RequestInfo {
                Headers = headers,
                Body = body,
            });

            var data = httpResult.Body;
            if (httpResult.StatusCode != 200)
            {
                var message = $"从接口获取{email}的信息失败";
                _logger.LogError("{Message}, httpResult: {@httpResult}", message, httpResult);
                throw new Exception($"{message}, httpResult: {JsonSerializer.Serialize(httpResult)}");
            }
            if ((httpResult.Headers.TryGetValue("Authorization", out var token) || httpResult.Headers.TryGetValue("authorization", out token)) && data != null)
            {
                 data.Token = token.Replace("Bearer ","");
                 return data;
            }
            _logger.LogError("无法获取用户的token, httpResult: {@httpResult}", httpResult);
            throw new Exception($"无法获取用户的token, httpResult: {JsonSerializer.Serialize(httpResult)}");
        }
        /// <summary>
        /// 更新用户资料
        /// </summary>
        /// <param name="loginInfo"></param>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public async Task<LoginResultInfo?> UpdateInfoAsync(UpdateUserInput updateUserInput)
        {
            var url = $"/customers/{updateUserInput.CustomerId}";
            var requestInfo = new RequestInfo
            {
                BearerToken = updateUserInput.Token,
                Body = updateUserInput.UserInfo,
            };
            var httpResult = await _httpHelper.SendAndParseAsync<LoginResultInfo>(url, HttpMethod.Patch, requestInfo);

            if(httpResult.StatusCode == 200)return httpResult.Body;

            _logger.LogError("更新远程用户信息失败, httpResult: {@httpResult}", httpResult);
            throw new Exception($"更新远程用户信息失败, httpResult: {JsonSerializer.Serialize(httpResult)}");
        }
    }
} 